package com.yst.webplugin.fieldhandler;

import com.yst.spring.context.SpringContext;
import com.yst.web.utils.BeanUtils;
import com.yst.web.utils.ClassUtils;
import com.yst.webplugin.annotation.*;
import com.yst.webplugin.loginplugin.UserUtils;
import com.yst.webplugin.util.ParamUtils;
import lombok.SneakyThrows;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.Objects;

public class CreateHandler implements IFieldHandler{
    @Override
    public boolean accept(Field field) {
        return Objects.nonNull(field.getAnnotation(Create.class));
    }

    @SneakyThrows
    @Transactional
    @Override
    public void handle(Field field, HttpInfo httpInfo) {

        Create create = field.getAnnotation(Create.class);
        Class<?> clazz=null;
        if (create.modelClass()!= Default.class){
            clazz=create.modelClass();
        }

        if (Objects.isNull(clazz)) {
            clazz=field.getType();
        }

        Object param = httpInfo.getBodyAs(clazz);

        ParamUtils.checkParams(param,create.validClass(),create.validClassGroup());

        Serializable saveModel = create.modelClass().newInstance();

        BeanUtils.copyProperties(param, saveModel, create.notSaveFields());

        if (ClassUtils.classExistsField(create.modelClass(),create.createUserIdField())) {
            BeanUtils.setFieldValue(create.createUserIdField(), saveModel, UserUtils.getCurrentUserId());
        }
        if (ClassUtils.classExistsField(create.modelClass(),create.createTimeField())) {
            BeanUtils.setFieldValue(create.createTimeField(), saveModel, new Date());
        }

        if (!create.onBeforeSave().equals(BeforeSave.class)) {
            BeforeSave beforeSave = SpringContext.getContext().getBean(create.onBeforeSave());
            beforeSave.beforeSave(saveModel, httpInfo);
        }

        List<Field> blist=ClassUtils.getClassFieldsByFieldClass(field.getDeclaringClass(), BeforeSave.class);
        for(Field bfield:blist){
            Object controller=SpringContext.getContext().getBean(bfield.getDeclaringClass());
            if (Objects.nonNull(controller)){
                BeforeSave beforeSave=(BeforeSave) bfield.get(controller);
                if(Objects.nonNull(beforeSave)){
                    beforeSave.beforeSave(saveModel,httpInfo);
                }
            }
        }


        SqlToyLazyDao sqlToyLazyDao = SpringContext.getContext().getBean(SqlToyLazyDao.class);
        sqlToyLazyDao.save(saveModel);

        List<Field> alist=ClassUtils.getClassFieldsByFieldClass(field.getDeclaringClass(), AfterSave.class);
        for(Field afield:alist){
            Object controller=SpringContext.getContext().getBean(afield.getDeclaringClass());
            if (Objects.nonNull(controller)){
                AfterSave afterSave=(AfterSave) afield.get(controller);
                if(Objects.nonNull(afterSave)){
                    afterSave.afterSave(saveModel,httpInfo);
                }
            }
        }

        if (!create.onAfterSave().equals(AfterSave.class)) {
            AfterSave afterSave = SpringContext.getContext().getBean(create.onAfterSave());
            afterSave.afterSave(saveModel, httpInfo);
        }

        httpInfo.writeResult(saveModel);
    }
}
